#include "header.h"

extern unsigned long dl;
//PSNR
float fpsnr(uint8_t *plane_rebuild,uint8_t* plane){
   unsigned long i;
   float mse=0.0;
   for(i=0;i<dl;i++)
      mse=mse+(float)(plane_rebuild[i]-plane[i])*(plane_rebuild[i]-plane[i]);
      mse=mse/dl;
      float psnr=20*log10(255)-10*log10(mse); 
      return psnr;
}

//SSIM
float average(uint8_t *x, unsigned long length_x){
    float avr_x =0.0;
    unsigned long i;
    for(i=0;i<length_x;i++)
        avr_x=avr_x+x[i];
    avr_x=avr_x/length_x;
    return avr_x; 
}

float variance(unsigned char *x,float avr_x, unsigned long length_x){
    float var_x=0.0;
    unsigned long i;
    for(i=0;i<length_x;i++)
        var_x=var_x+pow((x[i]-avr_x),2)/length_x;
    
    return var_x;
}



float cov(uint8_t *x, uint8_t *y,unsigned long length, float avr_x,float avr_y){
    float cov_xy=0;
    unsigned long i;
    for(i=0;i<length;i++)
       cov_xy=cov_xy+(x[i]-avr_x)*(y[i]-avr_y);
    cov_xy=cov_xy/length;
   
    return cov_xy;
   
}
float fssim(uint8_t *x, uint8_t *y){
// X is plane, Y is plane_rebuild

    float avr_x,avr_y,
          var_x,var_y,
          cov_xy;
    unsigned long length=dl;
    avr_x=average(x,length);
    avr_y=average(y,length);
    var_x=variance(x,avr_x,length);
    var_y=variance(y,avr_y,length);
    cov_xy=cov(x,y,length,avr_x,avr_y);
    float c1=pow((0.01*255),2);
    float c2=pow((0.03*255),2);
    float ssim;
    ssim=((2*avr_x*avr_y+c1)*(2*cov_xy+c2))/((pow(avr_x,2)+pow(avr_y,2)+c1)*(var_x+var_y+c2));
   return ssim;
}
